"""
意图分类器
负责识别用户查询的意图类型，决定调用哪个工具
"""

import re
import logging
from typing import Dict, List, Optional, Tuple
from dataclasses import dataclass
from enum import Enum

from ..utils.logger import setup_logger


class IntentType(Enum):
    """意图类型枚举"""
    TRAVEL_CONSULTATION = "travel_consultation"  # 旅游咨询
    ROUTE_PLANNING = "route_planning"  # 路线规划
    UNKNOWN = "unknown"  # 未知意图


@dataclass
class IntentResult:
    """意图识别结果"""
    intent: IntentType
    confidence: float
    extracted_params: Dict[str, str]
    reasoning: str


class IntentClassifier:
    """意图分类器"""
    
    def __init__(self):
        """初始化意图分类器"""
        self.logger = setup_logger(__name__)
        
        # 旅游咨询关键词
        self.travel_keywords = [
            # 推荐类
            "推荐", "介绍", "有什么", "哪些", "好玩", "好看", "好吃", "好逛",
            "景点", "美食", "餐厅", "小吃", "特色", "必去", "值得",
            "好玩的", "好看的", "好吃的", "好逛的", "值得去的",
            
            # 查询类
            "查询", "了解", "知道", "信息", "详情", "介绍", "攻略",
            "怎么玩", "怎么逛", "怎么吃", "注意事项", "开放时间",
            "门票", "价格", "费用", "交通", "住宿", "酒店",
            "有什么好", "有什么值得", "有什么推荐",
            
            # 地点类
            "成都", "贵阳", "北京", "上海", "广州", "深圳", "杭州", "南京",
            "大熊猫", "宽窄巷子", "锦里", "春熙路", "天府广场",
            
            # 活动类
            "旅游", "旅行", "游玩", "观光", "休闲", "娱乐", "购物",
            "游玩", "观光", "休闲娱乐"
        ]
        
        # 路线规划关键词
        self.route_keywords = [
            # 导航类
            "怎么去", "怎么走", "路线", "导航", "路径", "方向", "前往",
            "到达", "到达方式", "交通方式", "出行方式",
            
            # 距离时间类
            "多远", "多久", "多长时间", "距离", "时间", "路程",
            "步行", "骑车", "开车", "坐车", "公交", "地铁", "打车",
            
            # 地点指示
            "从", "到", "去", "往", "出发", "起点", "终点", "目的地"
        ]
        
        # 地点提取模式
        self.location_patterns = [
            r"从(.+?)到(.+?)",
            r"从(.+?)去(.+?)",
            r"(.+?)怎么去(.+?)",
            r"怎么从(.+?)到(.+?)",
            r"(.+?)到(.+?)怎么走",
            r"去(.+?)怎么走",
            r"到(.+?)怎么去",
            # 新增：只有出发地的情况
            r"从(.+?)出发",
            r"我在(.+?)",
            r"我 从 (.+?)出发",
            r"我从(.+?)出发",
            # 新增：只有目的地的情况
            r"我想去(.+?),",
            r"我想去(.+?)怎么走",
            r"去(.+?)怎么走",
            r"到(.+?)怎么走"
        ]
        
        self.logger.info("意图分类器初始化完成")
    
    def classify_intent(self, query: str) -> IntentResult:
        """
        分类用户查询意图
        
        Args:
            query: 用户查询文本
            
        Returns:
            意图识别结果
        """
        try:
            self.logger.info(f"开始意图分类: {query}")
            
            # 预处理查询
            processed_query = self._preprocess_query(query)
            
            # 计算各意图的得分
            travel_score = self._calculate_travel_score(processed_query)
            route_score = self._calculate_route_score(processed_query)
            
            # 提取参数
            extracted_params = self._extract_parameters(query)
            
            # 确定最终意图
            if route_score > travel_score and route_score > 0.3:
                intent = IntentType.ROUTE_PLANNING
                confidence = route_score
                reasoning = f"检测到路线规划关键词，得分: {route_score:.2f}"
            elif travel_score > 0.1:  # 降低旅游咨询的识别阈值
                intent = IntentType.TRAVEL_CONSULTATION
                confidence = travel_score
                reasoning = f"检测到旅游咨询关键词，得分: {travel_score:.2f}"
            else:
                intent = IntentType.UNKNOWN
                confidence = 0.0
                reasoning = "未识别到明确的意图关键词"
            
            result = IntentResult(
                intent=intent,
                confidence=confidence,
                extracted_params=extracted_params,
                reasoning=reasoning
            )
            
            self.logger.info(f"意图分类完成: {intent.value}, 置信度: {confidence:.2f}")
            return result
            
        except Exception as e:
            self.logger.error(f"意图分类失败: {e}")
            return IntentResult(
                intent=IntentType.UNKNOWN,
                confidence=0.0,
                extracted_params={},
                reasoning=f"分类过程出错: {str(e)}"
            )
    
    def _preprocess_query(self, query: str) -> str:
        """预处理查询文本"""
        # 转换为小写
        query = query.lower()
        
        # 移除标点符号
        query = re.sub(r'[^\w\s\u4e00-\u9fff]', ' ', query)
        
        # 移除多余空格
        query = ' '.join(query.split())
        
        return query
    
    def _calculate_travel_score(self, query: str) -> float:
        """计算旅游咨询得分"""
        score = 0.0
        matched_keywords = []
        
        for keyword in self.travel_keywords:
            if keyword in query:
                score += 1.0
                matched_keywords.append(keyword)
        
        # 改进的得分计算：基于匹配关键词数量，而不是归一化
        if score > 0:
            # 基础得分：每个匹配的关键词给0.2分
            base_score = score * 0.2
            # 奖励得分：匹配多个关键词时给予额外奖励
            bonus_score = min(0.3, (score - 1) * 0.1) if score > 1 else 0
            score = min(1.0, base_score + bonus_score)
        
        self.logger.debug(f"旅游咨询得分: {score:.2f}, 匹配关键词: {matched_keywords}")
        return score
    
    def _calculate_route_score(self, query: str) -> float:
        """计算路线规划得分"""
        score = 0.0
        matched_keywords = []
        
        for keyword in self.route_keywords:
            if keyword in query:
                score += 1.0
                matched_keywords.append(keyword)
        
        # 改进的得分计算：基于匹配关键词数量
        if score > 0:
            # 基础得分：每个匹配的关键词给0.25分
            base_score = score * 0.25
            # 奖励得分：匹配多个关键词时给予额外奖励
            bonus_score = min(0.3, (score - 1) * 0.1) if score > 1 else 0
            score = min(1.0, base_score + bonus_score)
        
        self.logger.debug(f"路线规划得分: {score:.2f}, 匹配关键词: {matched_keywords}")
        return score
    
    def _extract_parameters(self, query: str) -> Dict[str, str]:
        """提取查询中的参数"""
        params = {}
        
        # 提取地点信息
        for i, pattern in enumerate(self.location_patterns):
            matches = re.findall(pattern, query)
            if matches:
                for match in matches:
                    if isinstance(match, tuple) and len(match) == 2:
                        # 完整的出发地-目的地模式
                        origin, destination = match
                        params['origin'] = origin.strip()
                        params['destination'] = destination.strip()
                        break
                    elif isinstance(match, str):
                        if i >= 7 and i < 11:  # 只有出发地的模式（索引7-10）
                            # 只有出发地的情况
                            origin = match.strip()
                            params['origin'] = origin
                        elif i >= 11:  # 只有目的地的模式（索引11及以后）
                            # 只有目的地的情况
                            destination = match.strip()
                            params['destination'] = destination
                        break
                if params:  # 如果已经提取到参数，就退出
                    break
        
        # 提取出行方式
        transport_modes = {
            '步行': 'walking',
            '骑车': 'cycling', 
            '骑行': 'cycling',
            '开车': 'driving',
            '驾车': 'driving',
            '坐车': 'transit',
            '公交': 'transit',
            '地铁': 'transit',
            '打车': 'driving'
        }
        
        for mode, transport in transport_modes.items():
            if mode in query:
                params['transport_mode'] = transport
                break
        
        self.logger.debug(f"提取参数: {params}")
        return params
    
    def is_route_planning_intent(self, query: str) -> bool:
        """判断是否为路线规划意图"""
        result = self.classify_intent(query)
        return result.intent == IntentType.ROUTE_PLANNING
    
    def is_travel_consultation_intent(self, query: str) -> bool:
        """判断是否为旅游咨询意图"""
        result = self.classify_intent(query)
        return result.intent == IntentType.TRAVEL_CONSULTATION
    
    def get_missing_parameters(self, query: str, intent: IntentType) -> List[str]:
        """获取缺失的必要参数"""
        missing = []
        
        if intent == IntentType.ROUTE_PLANNING:
            params = self._extract_parameters(query)
            
            if not params.get('origin'):
                missing.append('出发地')
            
            if not params.get('destination'):
                missing.append('目的地')
        
        return missing
    
    def suggest_clarification(self, query: str, intent: IntentType) -> str:
        """建议用户澄清查询"""
        if intent == IntentType.ROUTE_PLANNING:
            missing = self.get_missing_parameters(query, intent)
            if missing:
                return f"为了为您规划路线，请提供以下信息：{', '.join(missing)}"
        
        return "请提供更详细的信息，以便我为您提供更好的帮助。"
